<template>
	<view class="vi_datetime">
		<view @click="openClick">
			<slot></slot>
		</view>
		<vi-dialog ref="viDatetime"
			:point="setting.point"
			:radius="setting.boxRadius"
			:size="size"
			:title="title"
			:useTitle="useTitle"
			:spaceInside="inSpaceInside"
			:spaceOutside="inSpaceOutside"
			:topbar="topbar"
			:bottombar="bottombar"
			:width="setting.width"
			:maxWidth="setting.maxWidth"
			:shift="shift"
			@event="onEvent">
			<view v-if="isDateType">
				<vi-calendar
					:value="value"
					:mode="setting.mode"
					:type="setting.type"
					:color="color"
					:textColor="textColor"
					:radius="setting.radius"
					:size="size"
					:plain="plain"
					:formatSet="formatSet"
					:weekSet="weekSet"
					:weekHeight="weekHeight"
					:rowHeight="rowHeight"
					:weekendType="weekendType"
					:weekendColor="weekendColor"
					:pickTime="pickType=='datetime'"
					:useSecond="useSecond"
					:rangeBgOpacity="rangeBgOpacity"
					:pickerRadius="setting.pickerRadius"
					:start="start"
					:end="end"
					:min="min"
					:max="max"
					:useLunar="useLunar"
					:tagList="tagList"
					:tipsFormat="tipsFormat"
					:resFormat="resFormat"
					:icon="icon"
					:text="textSetting"
					:disabled="disabled"
					:readOnly="readOnly"
					:useSubmitButton="false"
					@change="onChange"
					@ready="isReady"></vi-calendar>
			</view>
			<!-- 特殊选择类型，年 -->
			<view v-else-if="pickType=='year'">
				<vi-year
					:value="value"
					:mode="setting.mode"
					:type="setting.type"
					:color="color"
					:textColor="textColor"
					:radius="setting.radius"
					:size="size"
					:plain="plain"
					:titleHeight="setting.weekHeight"
					:rowHeight="setting.rowHeight"
					:rangeBgOpacity="rangeBgOpacity"
					:icon="icon"
					:text="textSetting"
					:start="start"
					:end="end"
					:min="min"
					:max="max"
					:disabled="disabled"
					:readOnly="readOnly"
					:useSubmit="false"
					@change="onChange"></vi-year>
			</view>
			<view v-else-if="['month', 'monthYear'].includes(pickType)">
				<vi-month
					:value="value"
					:mode="setting.mode"
					:useYear="pickType=='monthYear'"
					:type="setting.type"
					:color="color"
					:textColor="textColor"
					:radius="setting.radius"
					:size="size"
					:plain="plain"
					:titleHeight="setting.weekHeight"
					:rowHeight="setting.rowHeight"
					:rangeBgOpacity="rangeBgOpacity"
					:icon="icon"
					:text="textSetting"
					:start="start"
					:end="end"
					:min="min"
					:max="max"
					:disabled="disabled"
					:readOnly="readOnly"
					:useSubmit="false"
					:resFormat="resFormat"
					@change="onChange"></vi-month>
			</view>
		</vi-dialog>
	</view>
</template>

<script>
	export default {
		name:"viDatetime",
		props: {
			//主题色
			type:{
				type:[String,null],
				default:null
			},
			color:{
				type:[String,null],
				default:""
			},
			textColor:{
				type:[String,null],
				default:""
			},
			//日期圆角
			radius:{
				type:[Number,String,null],
				default:null
			},
			size:{
				type:[String,null],
				default:null
			},
			plain:{
				type:[Boolean,null],
				default:false
			},
			title:{
				type:[String,null],
				default:""
			},
			useTitle:{
				type:[Boolean,null],
				default:null
			},
			width:{
				type:[String,null],
				default:""
			},
			maxWidth:{
				type:[String,null],
				default:""
			},
			//外框用
			boxRadius:{
				type:[String,Number,null],
				default:null
			},
			buttonHeight:{
				type:[Number,null],
				default:0
			},
			value:{
				type:[String,Number,Date,Array,null],
				default:""
			},
			point:{
				type:[String,null],
				default:""
			},
			//选择类型，radio单选、checkbox多选、range选区
			mode:{
				type:[String,null],
				default:""
			},
			//特殊拾取类型，false(date)为日期类、datetime日期时间(强制为单选)、month月份、year年份、monthYear年月
			pickType:{
				type:[Boolean,String,null],
				default:false
			},
			//使用秒
			useSecond:{
				type:[Boolean,null],
				default:false
			},
			//单选立即提交
			activeSubmit:{
				type:[Boolean,null],
				default:false
			},
			formatSet:{
				type:[Object,null],
				default:()=>({})
			},
			weekSet:{
				type:[Object,null],
				default:()=>({})
			},
			//星期条高度，单位em
			weekHeight:{
				type:[Number,null],
				default:0
			},
			//日期单元格高，单位em
			rowHeight:{
				type:[Number,null],
				default:0
			},
			//周末主题色
			weekendType:{
				type:[String,null],
				default:""
			},
			//周末自定义色
			weekendColor:{
				type:[String,null],
				default:""
			},
			//选区背景透明度
			rangeBgOpacity:{
				type:[Number,null],
				default:null
			},
			//拾取器按钮圆角
			pickerRadius:{
				type:[String,Number,null],
				default:null
			},
			//开始范围
			start:{
				type:[Number,String,Date,null],
				default:""
			},
			//结束范围
			end:{
				type:[Number,String,Date,null],
				default:""
			},
			//最少选择，多选用
			min:{
				type:[Number,null],
				default:0
			},
			//最多选择，多选用
			max:{
				type:[Number,null],
				default:0
			},
			//使用农历标签
			useLunar:{
				type:[Boolean,null],
				default:false
			},
			//自定义标签
			tagList:{
				type:[Array,null],
				default:()=>[
					// {
					// 	name:"",	//标题
					// 	value:"",	//时间，天
					//	event:"",	//事件名
					// }
				]
			},
			//状态提示，日期格式
			tipsFormat:{
				type:[String,null],
				default:""
			},
			resFormat:{
				type:[String,null],
				default:""
			},
			//窗口偏移
			shift:{
				type:[Object,null],
				default:()=>({})
			},
			//框外间距
			spaceOutside:{
				type:[Number,String,Array,null],
				default:null
			},
			//框内间距
			spaceInside:{
				type:[Number,String,Array,null],
				default:null
			},
			icon:{
				type:[Object,null],
				default:()=>({})
			},
			text:{
				type:[Object,null],
				default:()=>({})
			},
			disabled:{
				type:[Boolean,null],
				default:false
			},
			readOnly:{
				type:[Boolean,null],
				default:false
			}
		},
		data() {
			return {
				inValue:null,
				dicText:{
					confirm: "确定",
					cancel: "取消"
				},
			}
		},
		computed: {
			//将默认值内含到css、计算属性等地方，只内含真值
			//规避特殊使用的情况下，由prop传入undefined、null等无效数据导致的，默认值失效问题。例如组件嵌套且需要组件间参数传递
			//HBuilder X3.3.13; 微信开发者工具stable 1.05.2111300
			//微信小程序会对传入的undefined、null值根据参数类型输出不同空值(false、""、null、0)，参数类型为null或未指定参数类型则输出null
			//H5会对传入的undefined取默认值，未设默认值则输出undefined。对传入的null值固定输出null
			//做参数传递时需警惕两者行为不同而造成的陷阱，主要问题出现在微信小程序的空值转化，输出非用户传入的空值、假值，使默认真值丢失
			//兼容空值取默认值的可行方案目前为，参数类型加入null如[Boolean,null]，判断传入参数是否为定义的类型，是则使用，否则赋予默认值
			setting(){
				return {
					point: this.point ||"bottom",
					type: this.$api.isDefined(this.type)? this.type :"primary",
					radius: this.$api.isDefined(this.radius)? this.radius :"0.5em",
					pickerRadius: this.$api.isDefined(this.pickerRadius)? this.pickerRadius :"0.25em",
					width: this.width ||"100vw",
					maxWidth: this.maxWidth ||"40em",
					weekHeight: this.weekHeight? this.weekHeight +"em" :"",//年、月组件需是字符串格式。日历组件使用数字，不使用该项
					rowHeight: this.rowHeight? this.rowHeight +"em" :"",//年、月组件需是字符串格式。日历组件使用数字，不使用该项
					boxRadius: this.$api.isDefined(this.boxRadius)? this.boxRadius :"0.5em",
					buttonHeight: this.buttonHeight ||3,
					mode: this.mode ||"radio",
				}
			},
			isDateType(){
				return !this.pickType || ["datetime", "date"].includes(this.pickType)
			},
			isRadio(){
				return this.setting.mode=="radio"
			},
			isCheckbox(){
				return this.setting.mode == "checkbox"
			},
			isRange(){
				return this.setting.mode == "range"
			},
			textSetting(){
				if(this.$api.isObject(this.text)){
					return Object.assign({},this.dicText,this.text)
				}
				return this.dicText
			},
			//顶部按钮
			topbar(){
				//底部弹窗
				if(this.setting.point == "bottom"){
					return {
						aside:true,
						buttonHeight: this.setting.buttonHeight,
						list:[
							{event:"cancel", name: this.textSetting.cancel, close:true},
							{event:"confirm", name: this.textSetting.confirm, type:this.setting.type, color:this.color}
						]
					}
				}
				return {}
			},
			bottombar(){
				//非底部弹窗
				if(this.setting.point!="bottom"){
					//非底部弹窗，给确定、取消按钮
					return {
						buttonHeight: this.setting.buttonHeight,
						list:[
							{event:"cancel", name: this.textSetting.cancel, close:true},
							{event:"confirm", name: this.textSetting.confirm, type:this.setting.type, color:this.color}
						]
					}
				}
				//底部弹窗使用顶部按钮
				return {}
			},
			inSpaceInside(){
				let res = this.spaceInside;
				if(!this.$api.isValue(res)){
					switch(this.setting.point){
						case "bottom":
							if(this.isCheckbox){
								return [0,0,"0.5em",0]
							}
							return 0
						case "center":
							return 0
						default:
							return ["0.5em",0,0,0]
					}
				}
				return res
			},
			inSpaceOutside(){
				let res = this.spaceOutside;
				if(!this.$api.isValue(res)){
					switch(this.setting.point){
						case "top":
							return "0.5em"
						case "bottom":
							return ["0.5em","0.5em","1.5em","0.5em"]
						default:
							return 0
					}
				}
				return res
			},
		},
		methods: {
			onChange(e){
				this.inValue =e;
				if(this.activeSubmit&&this.isRadio&&(!this.pickType||["date","month","year"].includes(this.pickType))){
					if(this.pickType=="year"){//延迟，让关闭动画完成后再触发数据刷新
						setTimeout(()=>{
							this.$emit("submit", e);
						},350)
					}else{
						this.$emit("submit", e);
					}
					this.close();
				}
			},
			//外部值变更导致的事件
			isReady(e){
				this.inValue =e;
			},
			//按钮点击事件
			onEvent(e){
				if(e.event=="confirm"){
					this.$emit("submit", this.inValue);
					this.close();
				}
			},
			openClick(){
				if(!this.disabled&&!this.readOnly){
					this.open()
				}
			},
			open(){
				//重置选中值
				this.inValue = this.value;
				this.$refs.viDatetime.open();
			},
			close(){
				setTimeout(()=>{
					this.$refs.viDatetime.close()
				},200)
			}
		},
		watch:{
			"value":{
				immediate:true,
				handler(newVal) {
					this.inValue = this.$api.isDefined(newVal)? newVal :"";
				}
			},
		}
	}
</script>

<style lang="scss">

</style>
